Use case: Interrupt cancellation

Sequence diagram

  @startuml
            participant "User application" as App
  participant "<font color=black><b>HAL FDCAN"  as FDCAN #19DD3A

  alt #LightSteelBlue Interrupt grouping available
  App -> FDCAN: HAL_FDCAN_ConfigInterruptLines(&hfdcan, FDCAN_IT_GROUP_SMSG, FDCAN_INTERRUPT_LINE0)
  else #LightCyan   Interrupt grouping not available
  App -> FDCAN: HAL_FDCAN_ConfigInterruptLines(&hfdcan, FDCAN_IT_TX_ABORT_COMPLETE, FDCAN_INTERRUPT_LINE0)
  end         FDCAN --> App:<color green>HAL_OK
  App -> FDCAN: HAL_FDCAN_ActivateNotification(&hfdcan, FDCAN_IT_TX_ABORT_COMPLETE, FDCAN_TX_BUFFER0)
  FDCAN --> App:<color green>HAL_OK

  App -> FDCAN: HAL_FDCAN_Start()
  FDCAN --> App:<color green>HAL_OK
  Note over App#lightyellow: Prepare the Tx Header

  == FDCAN HAL Message Transmit  ==
  App-> FDCAN: HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan, &TxHeader, TxData[0])
  FDCAN --> App:<color green>HAL_OK
  opt User want to cancel transmission
  App-> FDCAN: HAL_FDCAN_AbortTxRequest()
  note right
  In case the user wants to abort message transmission.
  end note
  FDCAN --> App:<color green>HAL_OK
  activate App #1000DA
  hnote over App
  <font color=blue>transmission ongoing...
  end note
  NVIC <-  : FDCAN interrupt Transmission cancellation finished
  NVIC -> FDCAN: HAL_FDCAN_IRQHandler
  FDCAN -> App: HAL_FDCAN_TxBufferAbortCallback()
  App --> FDCAN:
  deactivate App
  FDCAN --> NVIC:
  NVIC --> :
  deactivate App
  end
  App --> FDCAN: HAL_FDCAN_DeactivateNotification(&hfdcan, FDCAN_IT_TX_ABORT_COMPLETE)
  FDCAN --> App:<color green>HAL_OK
  @enduml

Code snippet

HAL1

HAL2

/* if interrupt grouping available */
HAL_FDCAN_ConfigInterruptLines(&hfdcan, FDCAN_IT_GROUP_SMSG,
                                        FDCAN_INTERRUPT_LINE0);
/* else */
HAL_FDCAN_ConfigInterruptLines(&hfdcan, FDCAN_IT_TX_ABORT_COMPLETE,
                                        FDCAN_INTERRUPT_LINE0);

HAL_FDCAN_ActivateNotification(&hfdcan,
                               FDCAN_IT_TX_ABORT_COMPLETE, FDCAN_TX_BUFFER0);


HAL_FDCAN_Start(&hfdcan);


TxHeader.Identifier          = 0x111;
TxHeader.IdType              = FDCAN_STANDARD_ID;
TxHeader.TxFrameType         = FDCAN_DATA_FRAME;
TxHeader.DataLength          = FDCAN_DLC_BYTES_8;
TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
TxHeader.BitRateSwitch       = FDCAN_BRS_ON;
TxHeader.FDFormat            = FDCAN_FD_CAN;
TxHeader.TxEventFifoControl  = FDCAN_NO_TX_EVENTS;
TxHeader.MessageMarker       = 0;

HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan, &TxHeader, &TxData[0]);
/* In case the user wants to abort message transmission */
HAL_FDCAN_AbortTxRequest(&hfdcan, FDCAN_TX_BUFFER0)
while (TransmissionAbortFlag == 0);

void HAL_FDCAN_TxBufferAbortCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes)
{
  TransmissionAbortFlag = 1U;
}
/* if interrupt grouping available*/
HAL_FDCAN_SetInterruptGroupsToLine(&hfdcan, HAL_FDCAN_IT_GROUP_STATUS_MSG,
                                            HAL_FDCAN_IT_LINE_0 );
/* else */
HAL_FDCAN_SetInterruptsToLine(&hfdcan, HAL_FDCAN_IT_TX_ABORT_COMPLETE,
                                      HAL_FDCAN_IT_LINE_0 );

HAL_FDCAN_EnableTxBufferCancellationInterrupts(&hfdcan, HAL_FDCAN_IT_TX_ABORT_BUFFER_0);

HAL_FDCAN_EnableInterrupts(&hfdcan,  HAL_FDCAN_IT_TX_ABORT_COMPLETE );
HAL_FDCAN_EnableInterruptLines(&hfdcan, HAL_FDCAN_IT_LINE_0);

HAL_FDCAN_Start(&hfdcan);

/* Prepare FDCAN transmit message header */
tx_element_header.b.identifier            = 0x111,
tx_element_header.b.identifier_type       = HAL_FDCAN_ID_STANDARD,
tx_element_header.b.frame_type            = HAL_FDCAN_FRAME_DATA,
tx_element_header.b.data_length           = HAL_FDCAN_DATA_LEN_CAN_FDCAN_8_BYTE,
tx_element_header.b.error_state_indicator = HAL_FDCAN_ERROR_STATE_IND_ACTIVE,
tx_element_header.b.bit_rate_switch       = HAL_FDCAN_BIT_RATE_SWITCH_ON,
tx_element_header.b.frame_format          = HAL_FDCAN_HEADER_FRAME_FORMAT_FD_CAN,
tx_element_header.b.event_fifo_control    = HAL_FDCAN_FIFO_STORE_TX_EVENTS,
tx_element_header.b.message_marker        = 0U,

HAL_FDCAN_ReqTransmitMsgFromFIFOQ(&hfdcan, &tx_element_header, pTxData);
/* In case the user wants to abort message transmission */
HAL_FDCAN_ReqAbortOfTxBuffer(&hfdcan, HAL_FDCAN_IT_TX_ABORT_BUFFER_0)
while (TransmissionAbortFlag == 0);

static void HAL_FDCAN_TxBufferAbortCallback(hal_fdcan_handle_t *hfdcan, uint32_t buffer_indexes)
{
  TransmissionAbortFlag = 1U;
}

Key changes

  1. HAL2 splits interrupt enablement into separate APIs for interrupt lines, interrupt sources, and Tx buffer cancellation interrupts.

  2. HAL2 uses HAL_FDCAN_ReqAbortOfTxBuffer() to request a Tx cancellation.